Skip to content

fix(modal): allow interaction with parent content through sheet modals in child routes#30839

Merged
ShaneK merged 9 commits into
mainfrom
fix/sheet-modals
Dec 10, 2025
Merged

fix(modal): allow interaction with parent content through sheet modals in child routes#30839
ShaneK merged 9 commits into
mainfrom
fix/sheet-modals

Conversation

@ShaneK

@ShaneK ShaneK commented Dec 5, 2025

Copy link
Copy Markdown
Member

Issue number: resolves #30700


What is the current behavior?

When a sheet modal with showBackdrop=false is rendered in a child route (nested ion-router-outlet), the parent content becomes non-interactive. Clicks on buttons or other interactive elements in the parent component are blocked, even though showBackdrop=false should allow background interaction.

Two separate issues contributed to this bug:

  1. Root locking with backdropBreakpoint: The shouldLockRoot logic in overlays.ts didn't account for backdropBreakpoint. Modals with backdropBreakpoint > 0 were still locking the root with aria-hidden, even though developers expect background interaction when the modal is below the backdrop breakpoint.
  2. Child route wrapper blocking: When a modal is in a child route, the child route's page wrapper (ion-page) and its parent ion-router-outlet remain in the DOM with position: absolute covering the viewport. Even after the modal is moved to ion-app and has pointer-events: none, these wrapper elements block clicks to the parent page's content.

This issue stems from #30563, which added root-locking behavior that didn't account for modals that allow background interaction. A partial fix in #30689 partially addressed showBackdrop=false and focusTrap=false, but missed backdropBreakpoint.

What is the new behavior?

Sheet modals with showBackdrop=false or focusTrap=false now correctly allow interaction with parent content when the modal is in a child route.
Improvements:

  • Recalculates isSheetModal in present() to handle Angular binding timing
  • Sets pointer-events: none on the modal element and its original parent elements when background interaction should be allowed
  • Cleans up pointer-events on dismiss
  • Adds regression tests

Does this introduce a breaking change?

  • Yes
  • No

Other information

Dev build:

8.7.12-dev.11765060985.14ad27fb

…e aren't allowing clicks through the background
@ShaneK ShaneK requested a review from a team as a code owner December 5, 2025 02:49
@ShaneK ShaneK requested a review from BenOsodrac December 5, 2025 02:49
@vercel

vercel Bot commented Dec 5, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
ionic-framework Ready Ready Preview Comment Dec 10, 2025 9:00pm

Comment thread core/src/components/modal/modal.scss Outdated
@ShaneK ShaneK marked this pull request as ready for review December 5, 2025 19:19
@ShaneK ShaneK changed the title fix(modal): allow interaction with parent content when sheet modal has showBackdrop=false in child routes fix(modal): allow interaction with parent content through sheet modals in child routes Dec 5, 2025

@thetaPC thetaPC left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main thing is that I couldn't get the Angular page to interact for me. Please let me know if I just missed something.

Comment thread core/src/components/modal/modal.tsx Outdated
…ages, caching page parent to prevent excessive searching

@brandyscarney brandyscarney left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking requests. Looks good!

Comment thread core/src/components/modal/modal.tsx
Comment thread core/src/utils/overlays.ts Outdated
Comment thread core/src/components/modal/modal.tsx Outdated
Comment thread core/src/components/modal/modal.tsx Outdated
@ShaneK ShaneK added this pull request to the merge queue Dec 10, 2025
Merged via the queue into main with commit b9e3cf0 Dec 10, 2025
51 checks passed
@ShaneK ShaneK deleted the fix/sheet-modals branch December 10, 2025 21:19
pull Bot pushed a commit to LoadsAForks/ionic-framework that referenced this pull request Jun 10, 2026
…onic-team#31202)

Issue number: internal

---------

## What is the current behavior?

Currently, when an `ion-modal`'s `breakpoints` are set after the
component has loaded, `sortedBreakpoints` stays empty.
`breakpointsChanged` had no `@Watch`, so it only ran once from the
manual call in `componentDidLoad`. `present()` still recalculates
`isSheetModal` to `true` from the late-set `breakpoints` (added in
ionic-team#30839), so the sheet gesture initializes with an empty breakpoints
array and throws `Reduce of empty array with no initial value` on the
`breakpoints.reduce(...)` in `sheet.ts` when the sheet is swiped, which
breaks swiping entirely.

This shows up with framework bindings that land after the web component
loads, e.g., an inline `ion-modal` inside an Angular component rendered
through a plain `router-outlet` with zoneless change detection. It
doesn't reproduce with zone change detection, with
`ModalController.create`, or with the modal inside `ion-router-outlet`,
since those set `breakpoints` before the modal presents.

## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->

Now `breakpointsChanged` has `@Watch('breakpoints')`, so `breakpoints`
set after the component loads update `sortedBreakpoints`. This mirrors
how `trigger`/`triggerChanged` already handles late binding (a watch
plus a manual call in `componentDidLoad`). The sheet gesture then gets
the real breakpoints and swiping works.

## Does this introduce a breaking change?

- [ ] Yes
- [X] No

## Other information

Sheet modal preview:
-
https://ionic-framework-git-fix-modal-late-breakpoints-ionic1.vercel.app/src/components/modal/test/sheet

Note that the preview won't show *this* working, but will show the modal
at least isn't broken from this change.

Current dev build:
```
8.8.10-dev.11781019195.14a7eeaf
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

package: angular @ionic/angular package package: core @ionic/core package package: react @ionic/react package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: sheet modals can't skip focus-traps on child routes

3 participants